#include"../logs/shwLog.h"
class SinkLog
    {
    public:
        using ptr = std::shared_ptr<shw::SinkLog>;
        virtual ~SinkLog() {}
        virtual void Log(const char *data, size_t len) = 0;
    };
    // 落地输出到标准显示器
    class StoutSink : public SinkLog
    {
    public:
        using ptr = std::shared_ptr<shw::StoutSink>;
        void Log(const char *data, size_t len) override
        {
            cout.write(data, len);
        }
    };
// 基于时间的滚动文件
    class RollBytimeSink : public SinkLog
    {
    public:
        RollBytimeSink(const std::string &baseName, size_t gapTime = 10 * 60 * 60)
            : _gapTime(gapTime), _baseName(baseName), _curTime(shw::util::date::Now())
        {
            shw::util::file::CreateDirectory(shw::util::file::Path(baseName)); // 创建目录
            std::string filename = createFilename();
            _ofs.open(filename, std::ios::binary | std::ios::app); // 打开文件
            assert(_ofs.is_open());                                // 打开失败，直接退出
        }
        void Log(const char *data, size_t len) override
        {
            auto tm = shw::util::date::Now();
            if (tm >= _curTime + _gapTime)
            {
                _ofs.close(); // 创建新文件之前，关闭之前的
                std::string filename = createFilename();
                _ofs.open(filename, std::ios::binary | std::ios::app);
                assert(_ofs.is_open()); // 打开失败，直接退出
                _curTime = tm;
            }
            _ofs.write(data, len);
            if (!_ofs.good())
            {
                cout << "写入文件失败！\n";
            }
        }
        std::string createFilename()
        {
            std::stringstream ss;
            auto time = shw::util::date::Now();
            struct tm lt;
            localtime_r(&time, &lt);
            ss << _baseName;
            ss << lt.tm_year + 1900;
            ss << lt.tm_mon + 1;
            ss << lt.tm_mday;
            ss << lt.tm_hour;
            ss << lt.tm_min;
            ss << lt.tm_sec;
            ss << '-';
            ss << ++_count;
            ss << ".log";
            return ss.str();
        }

    private:
        size_t _gapTime; // 时间间隔
        std::ofstream _ofs;
        std::string _baseName; // 基础文件名
        time_t _curTime;       // 当前文件创建时间
        size_t _count;
    };
void loggerTest(const std::string& name)
{

    shw::Logger::ptr lp = shw::getLogger(name);
    assert(lp.get());
    FATAL_LOG("------------example--------------------");
    lp->Debug("%s", "logger->debug");
    lp->Info("%s",  "logger->info");
    lp->Warn("%s",  "logger->warn");
    lp->Error("%s", "logger->error");
    lp->Fatal("%s", "logger->fatal");
    DEBUG_LOG("%s", "LOG_DEBUG");
    INFO_LOG("%s",  "LOG_INFO");
    WARN_LOG("%s",  "LOG_WARN");
    ERROR_LOG("%s", "LOG_ERROR");
    FATAL_LOG("%s", "LOG_FATAL");
    FATAL_LOG("---------------------------------------");

    std::string log_msg = "hello world-";
    size_t fsize = 0;
    size_t count = 0;
    while (count < 100000)
    {
        std::string msg = log_msg + std::to_string(count++);
        lp->Error("%s", msg.c_str());
    }
}

void functional_test() 
{
    shw::GlobalLoggerBuilder::ptr lbp(new shw::GlobalLoggerBuilder());
    lbp->Namebuilder("all_sink_logger");
    lbp->Formatbuilder("[%d][%c][%f:%l][%p] %m%n");
    lbp->Levelbuilder(shw::level::value::DEBUG);
    lbp->Sinkbuilder<shw::StoutSink>();
    lbp->Sinkbuilder<shw::FileSink>("./test_logs/sync.log");
    lbp->Sinkbuilder<shw::RollBytimeSink>("./test_logs/roll-",2);//以秒为单位
    lbp->LoggerTypebuilder(shw::LoggerType::LOGGER_ASYNC);
    lbp->Builder(); 
    loggerTest("all_sink_logger");
}
int main()
{
    functional_test();
    return 0;
}